package com.budwk.app.sqfw.services.impl;

import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.budwk.app.sqfw.dto.RiverChiefAssistantControllerDTO;
import com.budwk.app.sqfw.dto.RiverChiefAssistantDTO;
import com.budwk.app.sqfw.models.Sqfw_formSummary_new;
import com.budwk.app.sqfw.services.RiverChiefAssistantService;
import com.budwk.app.sqfw.services.SqfwFormsummaryNewService;
import com.budwk.app.sqfwDoc.vo.RiverChiefAssistantThirdRiverVO;
import com.budwk.app.sys.models.Sys_user;
import com.budwk.app.sys.services.SysUserService;
import com.budwk.app.util.HttpUtils;
import com.google.common.base.Splitter;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.nutz.integration.jedis.RedisService;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.trans.Trans;

import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @author ZY.Wang
 * @since 2024/6/12
 */
@IocBean
@Slf4j
public class RiverChiefAssistantServiceImpl implements RiverChiefAssistantService {

    private final Integer retryTimes = 10;

    private ThreadLocal<Integer> retryTimesLocal = ThreadLocal.withInitial(() -> retryTimes);

    private final String riverDataRedisKey = "river-chief-assistant-river-redis-key";

    @Inject
    private SysUserService sysUserService;
    @Inject
    private SqfwFormsummaryNewService sqfwFormsummaryNewService;
    @Inject
    private RedisService redisService;

    @Inject("taskQueryExecutor")
    private ThreadPoolExecutor taskQueryExecutor;

    @Override
    public List<RiverChiefAssistantThirdRiverVO> listRiver(String riverName) {
        // 先从redis中取出，如果没有数据那么就从第三方获取
        String riverDataStr = redisService.get(riverDataRedisKey);
        List<RiverChiefAssistantThirdRiverVO> queryList = Lists.newArrayList();
        if (StringUtils.isBlank(riverDataStr)) {
            queryList = getThirdRiverList();
        } else {
            queryList = JSONObject.parseArray(riverDataStr, RiverChiefAssistantThirdRiverVO.class);
        }

        if (StringUtils.isBlank(riverName)) return queryList;

        List<RiverChiefAssistantThirdRiverVO> resultList = Lists.newArrayList();
        for (RiverChiefAssistantThirdRiverVO river : queryList) {
            if (river.getHlmc().contains(riverName)) {
                resultList.add(river);
            }
        }
        return resultList;
    }

    @Override
    public void insert(String userId, RiverChiefAssistantControllerDTO insertDTO) {

        Sys_user sysUser = sysUserService.fetch(userId);

        Trans.exec(() -> {
            Sqfw_formSummary_new formSummary = new Sqfw_formSummary_new();
            formSummary.setFillDate(new Date());
            formSummary.setCreateBy(userId);
            formSummary.setCreateDate(new Date());
            formSummary.setUpdateBy(userId);
            formSummary.setUpdateDate(new Date());
            formSummary.setProvince(sysUser.getProvince());
            formSummary.setCity(sysUser.getCity());
            formSummary.setDistrict(sysUser.getDistrict());
            formSummary.setCounty(sysUser.getCounty());
            formSummary.setCommunity(sysUser.getCommunity());
            formSummary.setUnitId(sysUser.getUnitId());
            formSummary.setUnitName(sysUser.getUnitName());
            formSummary.setType("河长助手");

            formSummary.setParamData(insertDTO.getFormSummary().getParamData());
            sqfwFormsummaryNewService.insert(formSummary);

            taskQueryExecutor.execute(() -> {
                // wzy 2024-6-20 暂时取消河长提交到第三方
                // RiverChiefAssistantDTO assistantDTO = JSONObject.parseObject(insertDTO.getFormSummary().getParamData(), RiverChiefAssistantDTO.class);
                // waterEventAdd(assistantDTO);
            });
        });
    }

    // ----------------------------------------------------------------------------------------
    //  下面是一些私有的方法
    // ----------------------------------------------------------------------------------------
    private final String thirdApiBaseUrl = "https://www.ituzhi.com:1006/waterApi/";
    private final String thirdTokenRedisKey = "river-chief-assistant-third-token";

    /**
     * 获取第三方token
     *
     * @return token
     */
    private String getThirdGetToken() {
        String url = thirdApiBaseUrl + "third/token/getToken";
        String username = "sqxz_df";
        String password = "a123456";
        Map<String, String> paramMap = Maps.newHashMap();
        paramMap.put("username", username);
        paramMap.put("password", password);
        try {
            String responseStr = HttpUtil.post(url, JSONObject.toJSONString(paramMap));
            JSONObject responseJson = JSONObject.parseObject(responseStr);
            Integer code = responseJson.getInteger("code");
            if (code == 200 || code == 0) {
                retryTimesLocal.set(retryTimes);
                String newToken = responseJson.getString("data");
                redisService.set(thirdTokenRedisKey, newToken);
                return newToken;
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.warn("河长助手调用第三方获取token接口失败!!!");
        }
        return null;
    }

    /**
     * 获取第三方headMap
     *
     * @return 结果
     */
    private Map<String, String> getThirdHeadMap() {
        boolean refresh = retryTimesLocal.get() < retryTimes;
        String thirdToken = redisService.get(thirdTokenRedisKey);
        if (StringUtils.isBlank(thirdToken) || refresh) {
            thirdToken = getThirdGetToken();
        }
        Map<String, String> headMap = Maps.newHashMap();
        headMap.put("Authorization", "Bearer " + thirdToken);
        return headMap;
    }

    /**
     * 第三方事件添加
     *
     * @return 结果
     */
    private Integer waterEventAdd(RiverChiefAssistantDTO assistantDTO) {

        if (retryTimesLocal.get() <= 0) return 0;

        String url = "water-affairs/water-event/add";
        Map<String, Object> paramMap = Maps.newHashMap();

        // 事件类型
        Map<String, String> typeMap = Maps.newHashMap();
        typeMap.put("乱占", "1");
        typeMap.put("乱采", "2");
        typeMap.put("乱堆", "3");
        typeMap.put("乱建", "4");
        typeMap.put("其他", "5");
        String type = assistantDTO.getType();
        String classify = Optional.ofNullable(typeMap.get(type)).orElse("5"); // 如果没有传使用5
        paramMap.put("classify", classify);    // 问题类型 1.乱占 2.乱采 3乱堆 4 乱建 5其他	true	string

        paramMap.put("eventAddress", assistantDTO.getAddress());   //事件地点	true	string
        paramMap.put("eventDetail", assistantDTO.getRiskDescription());    // 事件描述	true	string
        paramMap.put("eventName", assistantDTO.getEventName());   // 事件名称	true	string
        paramMap.put("eventType", "1");   // 类型 1.巡河 2.运维	false	string

        Map<String, Object> geomMap = Maps.newHashMap();
        geomMap.put("type", "Point");
        ArrayList<String> locationList = Lists.newArrayList(Splitter.on(",").split(assistantDTO.getLocation()));
        List<Double> geoLocationList = Lists.newArrayList();
        for (String locationItem : locationList) {
            geoLocationList.add(Double.parseDouble(locationItem));
        }
        geomMap.put("coordinates", JSONObject.toJSONString(geoLocationList));
        paramMap.put("geom", geomMap);    // 经纬度	true	Object,示例：{"type":"Point","coordinates":[102.333094303,27.484908796]}
        paramMap.put("riverCode", assistantDTO.getRiverCode());   // 所属河流	true

        String requestUrl = thirdApiBaseUrl + url;

        String responseStr = HttpUtil.createPost(requestUrl).header("Authorization", getThirdHeadMap().get("Authorization"))
                .body(JSONObject.toJSONString(paramMap), "application/json").execute().body();
        if (StringUtils.isBlank(responseStr)) {
            log.warn("河长助手第三方上报接口失败!");
        }
        JSONObject responseJson = JSONObject.parseObject(responseStr);
        Integer code = responseJson.getInteger("code");
        if (code == 0 || code == 200) {
            return 1;
        } else if (code == 401) {
            retryTimesLocal.set(retryTimesLocal.get() - 1);
            return waterEventAdd(assistantDTO);
        }
        log.warn("河长助手第三方事件添加接口调用失败！");
        return 0;
    }

    private List<RiverChiefAssistantThirdRiverVO> getThirdRiverList() {

        if (retryTimesLocal.get() <= 0) return Lists.newArrayList();

        String url = thirdApiBaseUrl + "water-affairs/river/listRiverReachDict";
        String responseStr = HttpUtils.getRequest(url, getThirdHeadMap(), null);
        if (StringUtils.isBlank(responseStr)) return Lists.newArrayList();

        List<RiverChiefAssistantThirdRiverVO> resultList = Lists.newArrayList();

        JSONObject responseJson = JSONObject.parseObject(responseStr);
        Integer code = responseJson.getInteger("code");
        if (code == 200 || code == 0) {
            JSONArray dataArray = responseJson.getJSONArray("data");
            for (Object dataObj : dataArray) {
                RiverChiefAssistantThirdRiverVO vo = JSONObject.parseObject(JSONObject.toJSONString(dataObj), RiverChiefAssistantThirdRiverVO.class);
                resultList.add(vo);
            }
            redisService.setex(riverDataRedisKey, 60 * 60 * 24, JSONObject.toJSONString(resultList));   // 默认24小时有效
        } else if (code == 401) {
            retryTimesLocal.set(retryTimesLocal.get() - 1);
            getThirdGetToken();
            return getThirdRiverList();
        }
        return resultList;
    }
}
